package com.biz.primus.account.service;

import com.biz.primus.account.feign.AccountDegradedFeignClient;
import com.biz.primus.account.feign.AccountFeignClient;
import com.biz.primus.account.feign.AuthorityDegradedFeignClient;
import com.biz.primus.account.feign.AuthorityFeignClient;
import com.biz.primus.base.exception.BizCheckedException;
import com.biz.primus.model.sso.account.vo.UserResVo;
import com.biz.primus.model.sso.account.vo.UserVo;
import com.biz.primus.model.sso.auth.vo.GrantedAuthority;
import com.biz.primus.model.sso.auth.vo.MenuGroupVO;
import com.biz.primus.model.sso.auth.vo.UserAuthoritiesResVO;
import com.biz.primus.model.sso.auth.vo.UserAuthority;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.List;
import java.util.Set;

/**
 * Created by younger on 17/11/10.
 */
public class PrimusUserDetailService implements AuthenticationUserDetailsService<CasAssertionAuthenticationToken>{
    private static final Logger logger = LoggerFactory.getLogger(PrimusUserDetailService.class);

    @Autowired
    private AccountFeignClient accountFeignClient;

    @Autowired
    private AccountDegradedFeignClient accountDegradedFeignClient;

    @Autowired
    private AuthorityFeignClient authorityFeignClient;

    @Autowired
    private AuthorityDegradedFeignClient authorityDegradedFeignClient;

    @Override
    public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
        UserResVo user = null;
        try{
            user = accountFeignClient.getUserResVoById(token.getName());
        }catch (Throwable e){
            logger.error("===============获取用户信息失败，采用降级服务====================");
            try {
                user = accountDegradedFeignClient.getUserResVoById(token.getName());
            } catch (BizCheckedException e1) {
                logger.error("===============获取用户信息失败===============");
            }
        }

        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);

        UserAuthoritiesResVO userAuthoritiesResVO = null;
        try {
            userAuthoritiesResVO = authorityFeignClient.listUserMenusAndGrantedAuthorities(token.getName());
        } catch (Throwable e) {
            logger.error("===============获取用户信息失败，采用降级服务===============");
            try {
                userAuthoritiesResVO= authorityDegradedFeignClient.listUserMenusAndGrantedAuthorities(token.getName());
            } catch (BizCheckedException e1) {
                logger.error("===============获取用户信息失败===============");
            }
        }
        Set<GrantedAuthority> grantedAuthorities = userAuthoritiesResVO.getGrantedAuthorities();
        List<MenuGroupVO> menuGroups = (List<MenuGroupVO>)userAuthoritiesResVO.getMenuGroups();

        userVo.setMenuGroups(menuGroups);
        Set<UserAuthority> authorities = Sets.newHashSet();
        for (GrantedAuthority grantedAuthority : grantedAuthorities){
            authorities.add(new UserAuthority(grantedAuthority.getAuthority()));
        }
        userVo.setAuthorities(authorities);

        return userVo;
    }
}
